#ifndef RANDOM_H
#define RANDOM_H

namespace Cvekas {

/// MT19937 based PRNG
class Random
{
public:
	/// Constructor. Chooses seed based on time.
	Random();
	/// Constructor.
	Random(uint seed);

	// Linear distribution (ranges are inclusive)

	/// Returns random unsigned 32 bit integer
	uint randUInt();
	/// Returns random unsigned 32 bit integer in specific range
	uint randUInt(uint low, uint high);
	/// Returns random 32 bit integer
	int randInt();
	/// Returns random unsigned 32 bit integer in specific range
	int randInt(int low , int high);
	/// Returns floating point value in specified range
	float randFloat(float low = 0.0f, float high = 1.0f);

	// Normal distribution

	/// Returns random floating point value in normal distribution with 0 mean and 1 variance
	float normal();
	/// Returns random floating point value in normal distribution
	float normal(float mean, float variance);

private:
	void init(uint seed);
	void update_state();

	// Periods
	static const uint n = 624;
	static const uint m = 397;

	uint state[n];
	uint index;
};

} // namespace

#endif
